package com.moli.iov.handle.worker.his.mongodb;

import com.mongodb.*;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import lombok.extern.slf4j.Slf4j;
import org.bson.Document;
import org.springframework.stereotype.Component;

import java.util.*;

public class Mongo {

    private String host;

    private String port;

    private String dbname;

    private Integer connectionsPerHost;

    private Integer threadsAllowedToBlockForConnectionMultiplier;

    private Integer connectTimeout;

    private Integer maxWaitTime;

    private Boolean socketKeepAlive;

    private Integer socketTimeout;

    private MongoClient mongoClient;

    public Mongo(String host, String port,
                 String dbname, Integer connectionsPerHost,
                 Integer threadsAllowedToBlockForConnectionMultiplier,
                 Integer connectTimeout, Integer maxWaitTime, Boolean socketKeepAlive,
                 Integer socketTimeout) {
        this.host = host;
        this.port = port;
        this.dbname = dbname;
        this.connectionsPerHost = connectionsPerHost;
        this.threadsAllowedToBlockForConnectionMultiplier = threadsAllowedToBlockForConnectionMultiplier;
        this.connectTimeout = connectTimeout;
        this.maxWaitTime = maxWaitTime;
        this.socketKeepAlive = socketKeepAlive;
        this.socketTimeout = socketTimeout;
        try {
            MongoClientOptions.Builder builder = MongoClientOptions.builder();
            builder.connectionsPerHost(connectionsPerHost);
            builder.connectTimeout(connectTimeout);
            builder.threadsAllowedToBlockForConnectionMultiplier(threadsAllowedToBlockForConnectionMultiplier);
            builder.maxWaitTime(maxWaitTime);
            builder.socketKeepAlive(socketKeepAlive);
            builder.socketTimeout(socketTimeout);
            MongoClientOptions mongoClientOptions = builder.build();
            String [] hostnames = this.host.split(","), ports = this.port.split(",");
            List<ServerAddress> seeds = new ArrayList<>(hostnames.length);
            for(int i = 0; i < hostnames.length; i++){
                seeds.add(new ServerAddress(hostnames[i], new Integer(ports[i])));
            }
            mongoClient = new MongoClient(seeds, mongoClientOptions);
        }catch (Exception ex){
            throw new MongoClientException("Mongo client information not found.");
        }
    }

     public Set<String> find(String collectionName, Collection<String> collection){
        Set<String> newDocument = new HashSet<>();
         MongoDatabase mongoDatabase = mongoClient.getDatabase(this.dbname);
         BasicDBList basicDBList = new BasicDBList();
         basicDBList.addAll(collection);
         BasicDBObject fields = new BasicDBObject("$in", basicDBList);
         FindIterable<Document> documents = mongoDatabase.getCollection(collectionName).find(new Document("rowKey", fields));
         MongoCursor<Document> cursor = documents.iterator();
         try {
             while (cursor.hasNext()) {
                 Document item = cursor.next();
                 newDocument.add(item.getString("rowKey"));
             }
         } finally {
             cursor.close();
         }
        return newDocument;
     }

   public void saveAll(String collectionName, List<Document> collection){
        MongoDatabase mongoDatabase = mongoClient.getDatabase(this.dbname);
        mongoDatabase.getCollection(collectionName).insertMany(collection);
    }

}
